package pers.vic.system.system;

import java.io.Serializable;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.subject.Subject;
import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

import pers.vic.base.bo.system.Principal;
import pers.vic.base.contant.BaseConsoleConstant;
import pers.vic.base.controller.BaseConsoleController;
import pers.vic.system.shiro.FormAuthenticationFilter;
import pers.vic.system.system.service.SysMenuService;



/**
 * 理应最新进入的controller
 * @author VIC
 *
 */
@Controller
@RequestMapping("/console")
public class ConsoleIndexController extends BaseConsoleController{
	/*
	@Resource
	private UserService userService;
	*/
	@Resource
	private SysMenuService sysMenuService;
	
	@Resource
	private RedisTemplate<String, Object> redisTemplate;
	
	
	
	/**
	 * 后台理应最先进入的页面
	 */
	@RequestMapping(value = {"/",""})
	public String home(){
		return "console-index";
	}
	
	@RequestMapping(value = "/index")
	public String index(){
		return "console-index";
	}
	/**
	 *  进入登录页面
	 */
	@RequestMapping(value = "/login", method = RequestMethod.GET)
	public String login(){
		return "console-login";
	}
	
	/**
	 * 登录操作 失败的时候进入 真正的操作 是由Filter完成的(FormAuthenticationFilter.onLoginFailure)
	 */
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public String login(HttpServletRequest request, RedirectAttributes attr){
		Subject subject = SecurityUtils.getSubject();
		Principal principal = (Principal) subject.getPrincipal();
		if(principal != null) { //已经登录了
			generateNewSessionAndCacheOld();
			setSessionAttribute(BaseConsoleConstant.USER_SESSION_KEY, principal);
			return "redirect:" + BaseConsoleConstant.CONSOLE_INDEX;
		}
		String message = (String)request.getAttribute(FormAuthenticationFilter.DEFAULT_MESSAGE_PARAM);
		if(StringUtils.isEmpty(message)) {
			attr.addFlashAttribute(LOGIN_MSG, "用户名或者密码错误");
		}else {
			attr.addFlashAttribute(LOGIN_MSG, message);
		}
		return "redirect:/console/login";
//		String exceptionName = (String)request.getAttribute(FormAuthenticationFilter.DEFAULT_ERROR_KEY_ATTRIBUTE_NAME);
		
//		return "redirect:" + BaseConsoleConstant.CONSOLE_INDEX;
	}
	
	/**
	 *  清除SHIRO中老的session产生新的session,   
	 * 同时把缓存中的sessionId 替换为新的sessionId
	 * @see #loginCheck(String, String, String, String, String, String, DeviceOsTypeEnum, String, String, HttpServletRequest, HttpServletResponse)
	 * @see #logout(String)
	 */
	public void generateNewSessionAndCacheOld() {
		Subject subject = SecurityUtils.getSubject();
		Session sessionOld = subject.getSession();
		Serializable sessionOldId = sessionOld.getId();
		HashOperations<String, Serializable, SimpleSession> hashOperations = redisTemplate.opsForHash();
		String cacheName = "shiro-activeSessionCache";//参见SHIRO 的sessionDao原码里默认名
		//获取REDIS中的当前session
		SimpleSession cachedSessionSession = hashOperations.get(cacheName, sessionOldId);
		Serializable cachedSessionId = cachedSessionSession.getId();
		subject.logout();//退出登陆  产生新的session
		cachedSessionSession.setStopTimestamp(null);//非常重要
		Session sessionNew = subject.getSession();
		Serializable sessionNewId = sessionNew.getId();
		//cache old
		hashOperations.put(cacheName, sessionOldId, cachedSessionSession);
		// cache new
		cachedSessionSession.setId(sessionNewId);
		hashOperations.put(cacheName, sessionNewId, cachedSessionSession);
		redisTemplate.opsForValue().set("" + sessionNewId, cachedSessionId);
	}
	//退出登录
	@RequestMapping(value = "/logout", method = RequestMethod.GET)
	public String logout(HttpServletRequest request){
		Subject subject = SecurityUtils.getSubject();
		subject.logout();
		setSessionAttribute(BaseConsoleConstant.USER_SESSION_KEY, null);
		if(currentSession() != null) {
			currentSession().invalidate();
		}
		return "redirect:" + BaseConsoleConstant.CONSOLE_INDEX;
	}
	
	
}
